package actions 
{
	import com.greensock.easing.Linear;
	import com.greensock.TweenLite;
	import core.App;
	import flash.display.Graphics;
	import flash.display.Shape;
	import view.scene.Scene;
	/**
	 * ...
	 * @author Johnny Cheng
	 */
	public class DissolveAction 
	{
		public var p:Number = 1;
		
		private var _indices:Array = [];
		private var _pixelSize:Number = 40;
		
		private var _oldScene:Scene;
		private var _newScene:Scene;
		private var _oldMasker:Shape;
		private var _newMasker:Shape;
		
		public function DissolveAction(oldScene:Scene, newScene:Scene) 
		{
			if (oldScene == null) return;
			oldScene.mouseChildren = newScene.mouseChildren = false;
			
			for (var i:int = 0; i < App.stage.stageWidth; i += _pixelSize) {
				for (var j:int = 0; j < App.stage.stageHeight; j += _pixelSize) {
					_indices.push( { x:i, y:j } );
				}
			}
			shuffleArray(_indices);
			
			newScene.visible = false;
			
			_oldScene = oldScene;
			_newScene = newScene;
			
			_oldMasker = new Shape();
			_oldScene.addChild(_oldMasker);
			_oldScene.mask = _oldMasker;
			
			TweenLite.to(this, 0.5, { p:0, onUpdate:onOldUpdate, onComplete:onOldComplete, ease:Linear.easeNone } );
		}
		
		private function shuffleArray(a:Array):void
		{
			for (var i:int = a.length - 1; i > 0;--i) {
				var k:int = Math.floor(Math.random() * (i + 1));
				if (k == i) continue;
				var tmp:Object = a[i];
				a[i] = a[k];
				a[k] = tmp;
			}
		}
		
		private function onOldUpdate():void 
		{
			drawMasker(_oldMasker.graphics);
		}
		
		private function onOldComplete():void 
		{
			_oldScene.removeChild(_oldMasker);
			_oldMasker = null;
			_oldScene.mask = null;
			_oldScene.removeSelf();
			
			_newScene.visible = true;
			_newMasker = new Shape();
			_newScene.addChild(_newMasker);
			_newScene.mask = _newMasker;
			shuffleArray(_indices);
			TweenLite.to(this, 0.5, { p:1, onUpdate:onNewUpdate, onComplete:onNewComplete, ease:Linear.easeNone } );
		}
		
		private function onNewUpdate():void 
		{
			drawMasker(_newMasker.graphics);
		}
		
		private function onNewComplete():void 
		{
			_newScene.removeChild(_newMasker);
			_newMasker = null;
			_newScene.mask = null;
			_newScene.mouseChildren = true;
		}
		
		private function drawMasker(g:Graphics):void
		{
			g.clear();
			g.beginFill(0);
			var loop:int = Math.round(p * _indices.length);
			for (var i:int = 0; i < loop; i++) {
				var o:Object = _indices[i];
				g.drawRect(o.x, o.y, _pixelSize, _pixelSize);
			}
			g.endFill();
		}
	}

}